import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;


public class Node {
    /* ======================================================
     * MEMBERS
     * ====================================================== */
    private String _category;
    private HashMap<String, Node> _children;
    private Integer _coverage;
    private ArrayList<String> _documentSample;
    private Node _parent;
    private HashMap<String, ArrayList<String>> _queries;
    private Double _specificity;

    /* ======================================================
     * CONSTRUCTORS
     * ====================================================== */
    public Node(Node parent, String category){
	this._parent = parent;
	this._children = new HashMap<String, Node>();
	this._queries = new HashMap<String, ArrayList<String>>();
	_coverage = 0;
	_specificity = 0.0;
	this._category = category;
    }

    /* ======================================================
     * METHODS
     * ====================================================== */
    public void addQuery(String cat, String query){
	if (!this._queries.containsKey(cat)){
	    this._queries.put(cat, new ArrayList<String>());
	}
	if (!this._queries.get(cat).contains(query)){
	    this._queries.get(cat).add(query);
	}
    }

    public void buildTree(String filename){
	try {
	    String line = null;
	    //Check to see if the file exists
	    File f = new File(filename);
	    if (f.exists()){
		// Open file
		BufferedReader in = new BufferedReader(new FileReader(filename));
		while ((line = in.readLine()) != null) {
		    //get the category
		    String _category = line.split("\\s")[0].trim();

		    //check to see if we have a child node for this category. If not, create one.
		    if (!this._children.containsKey(_category)){
			this._children.put(_category, new Node(this, _category));
		    }

		    //add the query to this node
		    String _query = line.replace(_category, "").trim();
		    this.addQuery(_category, _query);
		}
		in.close();

		//iterate through each child and build the subtrees
		for (Map.Entry<String, Node> entry : this._children.entrySet()){
		    entry.getValue().buildTree("lib/" + entry.getKey().toLowerCase() + ".txt");
		}
	    }
	} catch (FileNotFoundException e) {
	    e.printStackTrace();
	} catch (IOException e) {
	    e.printStackTrace();
	}
    }

    public String getCategory(){
	return this._category;
    }
    
    public HashMap<String, Node> getChildren(){
	return this._children;
    }

    public Integer getCoverage(){
	return this._coverage;
    }
    
    public ArrayList<String> getDocumentSample(){
	return this._documentSample;
    }
    
    public Node getParent(){
	return this._parent;
    }

    public HashMap<String, ArrayList<String>> getQueries(){
	return this._queries;
    }
    
    public Double getSpecificity(){
	return this._specificity;
    }
    
    public void setCoverage(Integer c){
	this._coverage = c;
    }
    
    public void setSpecificity(Double s){
	this._specificity = s;
    }
}
